﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.IO;
using WindowsGame1;

namespace WindowsGame3
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Texture2D BackGround;
        //Текстури земли
         Texture2D G1;
         Texture2D G2;
         Texture2D G3;
         Texture2D G4;
         Texture2D G5;
         Texture2D G6;
         Texture2D G7;
         Texture2D G8;
        //Доп Текстури
         Texture2D B1;
         Texture2D B2;
         Texture2D B3;
         Texture2D B4;
         Texture2D B5;
         Texture2D B6;
         Texture2D B7;
        //Текстури платформ
         Texture2D M1;
         Texture2D M2;
         Texture2D M3;
         Texture2D M4;

         List<Layer> Bloks;
         List<Layer> BackBloks;

         Texture2D run;// текстура руху
         Texture2D idle;//текстура зупинки
         Texture2D kill;//текстура стрільби в режимі стоячи
         Texture2D down;//текстура присідання
         Texture2D killrun;//текстура стрільби в режимі руху
         Texture2D killdown;//текстура стрільби в режимі присідання
         Texture2D jump; //текстура прижка

         SpriteAnimation hero;//основна зміннна класу SpriteAnimation
         KeyboardState oldstate;//змінна старого натиснення на клавіатуру

         public int width; //ширина екрану гри
         public int height; // висота екрану гри

         int Level = 0;

         static int ScrollX;
         static int ScrollY;
         public int levelLength;
         public int levelHeight = 0;


        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            width = graphics.PreferredBackBufferWidth = 960;
            height = graphics.PreferredBackBufferHeight = 600;
            Content.RootDirectory = "Content";

        }
        //перевірка на перетин героя з блоками
        public bool ColidesWithLevel(Rectangle rect)
        {
            foreach (Layer block in Bloks)
            {
                if (block.rect.Intersects(rect))
                    return true;
            }
            return false;
        }

        public static Rectangle GetScreenRect(Rectangle rect)
        {
            Rectangle screenRect = rect;
            screenRect.Offset(-ScrollX, -ScrollY);
            return screenRect;
        }

        public void ScrollXn(int dx)
        {
            if (ScrollX + dx >= 0 && ScrollX + dx <= levelLength - 960)
                ScrollX += dx;
        }
        public void ScrollYn(int dy)
        {
            if (ScrollY + dy >= 0 && ScrollY + dy  <= levelHeight - 600)
            {
                ScrollY +=10*dy; 
            }
        }

        public void CreateLeyer1()
        {
            Level = 1;
            Bloks = new List<Layer>();
            int x = 0;
            int y = 0;
                string[] s1 = File.ReadAllLines("content/Levels/Level"+Level+"/Leyer1.txt");
                levelLength = 40 * s1[0].Length;
                levelHeight = 1400;
                foreach (string str1 in s1)
                {
                   
                    foreach (char c in str1)
                    { 
                        Rectangle rect = new Rectangle(x, y, 40, 40);
                        switch (c)
                        {
                            case '1':
                                {
                                    Layer blok = new Layer(rect, M1);
                                    Bloks.Add(blok);
                                } break;
                            case '2':
                                {
                                    Layer blok = new Layer(rect, M2);
                                    Bloks.Add(blok);
                                } break;
                            case '3':
                                {
                                    Layer blok = new Layer(rect, M3);
                                    Bloks.Add(blok);
                                } break;
                            case '4':
                                {
                                    Layer blok = new Layer(rect, M4);
                                    Bloks.Add(blok);
                                } break;
                            case '5':
                                {
                                    Layer blok = new Layer(rect, G1);
                                    Bloks.Add(blok);
                                } break;
                            case '6':
                                {
                                    Layer blok = new Layer(rect, G2);
                                    Bloks.Add(blok);
                                } break;
                            case '7':
                                {
                                    Layer blok = new Layer(rect, G3);
                                    Bloks.Add(blok);
                                } break;
                            case '8':
                                {
                                    Layer blok = new Layer(rect, G4);
                                    Bloks.Add(blok);
                                } break;
                            case '9':
                                {
                                    Layer blok = new Layer(rect, G5);
                                    Bloks.Add(blok);
                                } break;
                            case 'a':
                                {
                                    Layer blok = new Layer(rect, G6);
                                    Bloks.Add(blok);
                                } break;
                            case 'b':
                                {
                                    Layer blok = new Layer(rect, G7);
                                    Bloks.Add(blok);
                                } break;
                            case 'c':
                                {
                                    Layer blok = new Layer(rect, G8);
                                    Bloks.Add(blok);
                               
                                } break;
                    }
                        x += 40;
                    }
                    x = 0;
                    y += 40;
                }       
        }

        public void CreateLeyer2()
        {
            BackBloks = new List<Layer>();
            int x = 0;
            int y = 0;
            string[] s2 = File.ReadAllLines("content/Levels/Level" + Level + "/Leyer2.txt");
            foreach (string str2 in s2)
            {
                foreach (char c in str2)
                {
                    Rectangle rect = new Rectangle(x, y, 120, 120);
                    switch (c)
                    {
                        case '1':
                            {
                                Layer blok = new Layer(rect, B1);
                                BackBloks.Add(blok);
                            } break;
                        case '2':
                            {
                                Layer blok = new Layer(rect, B2);
                                BackBloks.Add(blok);
                            } break;
                        case '3':
                            {
                                Layer blok = new Layer(rect, B3);
                                BackBloks.Add(blok);
                            } break;
                        case '4':
                            {
                                Layer blok = new Layer(rect, B4);
                                BackBloks.Add(blok);
                            } break;
                        case '5':
                            {
                                Layer blok = new Layer(rect, B5);
                                BackBloks.Add(blok);
                            } break;
                        case '6':
                            {
                                Layer blok = new Layer(rect, B6);
                                BackBloks.Add(blok);
                            } break;
                    }
                    x += 120;
                }
                x = 0;
                y += 120;
            }

        }
        protected override void Initialize()
        {
            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            //Загрузка ресурсів.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            run = Content.Load<Texture2D>("Textures/Sprites/RunGame");
            idle = Content.Load<Texture2D>("Textures/Sprites/StopRun");
            kill = Content.Load<Texture2D>("Textures/Sprites/KillUp");
            down = Content.Load<Texture2D>("Textures/Sprites/Down");
            killrun = Content.Load<Texture2D>("Textures/Sprites/KillRun");
            killdown = Content.Load<Texture2D>("Textures/Sprites/Downkill");
            jump = Content.Load<Texture2D>("Textures/Sprites/Jump");
            Rectangle rect = new Rectangle(0, height - (int)(3.2f*idle.Height), 160, 167);
            hero = new SpriteAnimation(rect, idle, run, kill, down, killrun, killdown, jump, this);

            //Задній фон
            BackGround = Content.Load<Texture2D>("Textures/Mod");
            //Земля
            G1 = Content.Load<Texture2D>("Textures/Bounds/Grounds/G5");
            G2 = Content.Load<Texture2D>("Textures/Bounds/Grounds/G1");
            G3 = Content.Load<Texture2D>("Textures/Bounds/Grounds/G2");
            G4 = Content.Load<Texture2D>("Textures/Bounds/Grounds/G3");
            G5 = Content.Load<Texture2D>("Textures/Bounds/Grounds/G4");
            G6 = Content.Load<Texture2D>("Textures/Bounds/Grounds/G6");
            G7 = Content.Load<Texture2D>("Textures/Bounds/Grounds/G7");
            G8 = Content.Load<Texture2D>("Textures/Bounds/Grounds/G8");
            //Проміжний фон
            B1 = Content.Load<Texture2D>("Textures/BackGrounds/Blok1");
            B2 = Content.Load<Texture2D>("Textures/BackGrounds/Blok2");
            B3 = Content.Load<Texture2D>("Textures/BackGrounds/Blok3");
            B4 = Content.Load<Texture2D>("Textures/BackGrounds/Blok4");
            B5 = Content.Load<Texture2D>("Textures/BackGrounds/Blok5");
            B6 = Content.Load<Texture2D>("Textures/BackGrounds/Blok6");
            //Борти
            M1 = Content.Load<Texture2D>("Textures/Bounds/Borts/M1");
            M2 = Content.Load<Texture2D>("Textures/Bounds/Borts/M2");
            M3 = Content.Load<Texture2D>("Textures/Bounds/Borts/M3");
            M4 = Content.Load<Texture2D>("Textures/Bounds/Borts/BL");
            //Створення Карти
           CreateLeyer1();
            CreateLeyer2(); 
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            KeyboardState keyboardstate = Keyboard.GetState();//поточне натиснення на клавіатуру
            if (keyboardstate.IsKeyDown(Keys.Escape)) this.Exit();

            Rectangle heroScreenRect = GetScreenRect(hero.rect);
                    if (heroScreenRect.Left < width / 2) 
                        ScrollXn(-gameTime.ElapsedGameTime.Milliseconds/4);
                    if (heroScreenRect.Left > width / 2)
                        ScrollXn(gameTime.ElapsedGameTime.Milliseconds/4);
                    if (heroScreenRect.Top +7 < height / 2)
                        ScrollYn(-gameTime.ElapsedGameTime.Milliseconds/10);
                    if (heroScreenRect.Top+7 > height / 2)
                        ScrollYn(gameTime.ElapsedGameTime.Milliseconds/10);

                    if (hero.RunLeft == false && keyboardstate.IsKeyDown(Keys.Space))
                        hero.Jump(false);
                    else
                        if (hero.RunLeft == true && keyboardstate.IsKeyDown(Keys.Space))
                            hero.Jump(true);
                        else
                            if (hero.isjumping == true && hero.RunLeft == false && keyboardstate.IsKeyDown(Keys.Right))
                                hero.JumpLeft = false;
                            else
                                if (hero.isjumping == true && hero.RunLeft == true && keyboardstate.IsKeyDown(Keys.Left))
                                    hero.JumpLeft = true;
                                else
                                    if (hero.RunLeft == false && keyboardstate.IsKeyDown(Keys.Right) && keyboardstate.IsKeyDown(Keys.RightShift))
                                        hero.KillRun(false);
                                    else
                                        if (hero.RunLeft == true && keyboardstate.IsKeyDown(Keys.Left) && keyboardstate.IsKeyDown(Keys.RightShift))
                                            hero.KillRun(true);
                                        else
                                            if (keyboardstate.IsKeyDown(Keys.Right))
                                                hero.Run(false);
                                            else
                                                if (oldstate.IsKeyDown(Keys.Right) && keyboardstate.IsKeyUp(Keys.Right))
                                                    hero.Stop(false);
                                                else
                                                    if (keyboardstate.IsKeyDown(Keys.Left))
                                                        hero.Run(true);
                                                    else
                                                        if (oldstate.IsKeyDown(Keys.Left) && keyboardstate.IsKeyUp(Keys.Left))
                                                            hero.Stop(true);
                                                        else
                                                            if (hero.RunLeft == false && keyboardstate.IsKeyDown(Keys.Down))
                                                                hero.Down(false);
                                                            else
                                                                if (hero.RunLeft == true && keyboardstate.IsKeyDown(Keys.Down))
                                                                    hero.Down(true);
                                                                else
                                                                    if (hero.downleft == false && oldstate.IsKeyDown(Keys.Down) && keyboardstate.IsKeyUp(Keys.Down))
                                                                        hero.Stop(false);
                                                                    else
                                                                        if (hero.downleft == true && oldstate.IsKeyDown(Keys.Down) && keyboardstate.IsKeyUp(Keys.Down))
                                                                            hero.Stop(true);
                                                                        else
                                                                            if (hero.isStopLeft == false && keyboardstate.IsKeyDown(Keys.RightShift))
                                                                                hero.KillUp(false);
                                                                            else
                                                                                if (hero.isStopLeft == true && keyboardstate.IsKeyDown(Keys.RightShift))
                                                                                    hero.KillUp(true);
                                                                                else
                                                                                    if (hero.KillUpLeft == false && oldstate.IsKeyDown(Keys.RightShift) && keyboardstate.IsKeyUp(Keys.RightShift))
                                                                                        hero.Stop(false);
                                                                                    else
                                                                                        if (hero.KillUpLeft == true && oldstate.IsKeyDown(Keys.RightShift) && keyboardstate.IsKeyUp(Keys.RightShift))
                                                                                            hero.Stop(true);
            oldstate = keyboardstate;
            hero.Update(gameTime);    

            // TODO: Add your update logic here

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
          
            spriteBatch.Begin();
            //3 рівень фон
            spriteBatch.Draw(BackGround, new Vector2(0, 0), Color.White); 
            spriteBatch.Draw(BackGround, new Vector2(400, 0), Color.White);
            spriteBatch.Draw(BackGround, new Vector2(800, 0), Color.White);
            //2 рівень проміжний фон
            foreach (Layer blok in BackBloks)
            {
                blok.Draw(spriteBatch);
            }
            //1 рівень борти
            foreach (Layer blok in Bloks)
            {
                blok.Draw(spriteBatch);
            }
            //Місце для спрайтів та кнопок
            spriteBatch.End();
            hero.Draw(spriteBatch);

            base.Draw(gameTime);
        }
        
    }
}
